package com.urbane.auth.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

/**
 * 认证操作日志切面
 * 功能：
 *   - 拦截登录、登出、刷新 Token 操作
 *   - 记录操作类型、用户ID、IP地址、设备信息
 *   - 写入审计日志，便于追溯
 * <p>
 * 注意：
 *   - 必须配合 MDC（Mapped Diagnostic Context）使用
 *   - 日志中自动携带 traceId、userId
 */
@Slf4j
@Aspect
@Component
public class AuthLogAspect {
    @Around("execution(* com.urbane.auth.service.impl.AuthServiceImpl.login(..)) || " +
            "execution(* com.urbane.auth.service.impl.AuthServiceImpl.refreshToken(..))")
    public Object logAuthOperation(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取当前被拦截的方法名
        String methodName = joinPoint.getSignature().getName();
        String ip = getCurrentIp(); // 从 HttpServletRequest 获取（需注入）

        // 从 ThreadLocal 获取当前用户ID（由过滤器设置）
        Long userId = 123456L;

        log.info("【认证操作】{} | userId={} | ip={}", methodName, userId, ip);

        try {
            Object result = joinPoint.proceed();
            log.info("【认证操作成功】{} | userId={}", methodName, userId);
            return result;
        } catch (Exception e) {
            log.warn("【认证操作失败】{} | userId={} | error={}", methodName, userId, e.getMessage());
            throw e;
        }
    }

    private String getCurrentIp() {
        // 实际项目中可通过 RequestContextHolder 获取 HttpServletRequest
        // 此处简化，仅作示意
        return "127.0.0.1";
    }
}
